package com.inspsys.common.utils.file;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
import java.util.Base64;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.poi.util.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.inspsys.common.config.InspSysConfig;
import com.inspsys.common.constant.Constants;
import com.inspsys.common.utils.StringUtils;

/**
 * 图片处理工具类
 *
 * @author inspsys
 */
public class ImageUtils {
    private static final Logger log = LoggerFactory.getLogger(ImageUtils.class);

    public static byte[] getImage(String imagePath) {
        InputStream is = getFile(imagePath);
        try {
            return IOUtils.toByteArray(is);
        } catch (Exception e) {
            log.error("图片加载异常 {}", e);
            return null;
        } finally {
            IOUtils.closeQuietly(is);
        }
    }

    public static InputStream getFile(String imagePath) {
        try {
            byte[] result = readFile(imagePath);
            result = Arrays.copyOf(result, result.length);
            return new ByteArrayInputStream(result);
        } catch (Exception e) {
            log.error("获取图片异常 {}", e);
        }
        return null;
    }

    /**
     * 读取文件为字节数据
     * 
     * @param url 地址
     * @return 字节数据
     */
    public static byte[] readFile(String url) {
        InputStream in = null;
        try {
            if (url.startsWith("http")) {
                // 网络地址
                URL urlObj = new URL(url);
                URLConnection urlConnection = urlObj.openConnection();
                urlConnection.setConnectTimeout(30 * 1000);
                urlConnection.setReadTimeout(60 * 1000);
                urlConnection.setDoInput(true);
                in = urlConnection.getInputStream();
            } else {
                // 本机地址
                String localPath = InspSysConfig.getProfile();
                String downloadPath = localPath + StringUtils.substringAfter(url, Constants.RESOURCE_PREFIX);
                in = new FileInputStream(downloadPath);
            }
            return IOUtils.toByteArray(in);
        } catch (Exception e) {
            log.error("获取文件路径异常 {}", e);
            return null;
        } finally {
            IOUtils.closeQuietly(in);
        }
    }

    /**
     * 将Base64编码的字符串生成图片
     *
     * @param base64Str  Base64编码的字符串
     * @param outputPath 输出图片的路径
     * @return 是否成功生成图片
     */
    public static boolean generateImageFromBase64(String base64Str, String name, String outputPath) {
        if (base64Str == null || base64Str.isEmpty()) {
            log.error("Base64字符串为空");
            return false;
        }
        try (OutputStream out = new FileOutputStream(
                outputPath + File.separator + name + "." + getImageExtensionFromBase64(base64Str))) {
            // 去除Base64字符串前缀
            if (base64Str.contains(",")) {
                base64Str = base64Str.substring(base64Str.indexOf(",") + 1);
            }
            // 解码Base64字符串
            byte[] decodedBytes = Base64.getDecoder().decode(base64Str);
            // 写入文件
            out.write(decodedBytes);
            return true;
        } catch (Exception e) {
            log.error("生成图片异常 {}", e);
            return false;
        }
    }

    /**
     * 从Base64编码的字符串中获取图片扩展名
     *
     * @param base64 Base64编码的字符串
     * @return 图片扩展名
     */
    public static String getImageExtensionFromBase64(String base64) {
        // 默认为png
        String extension = "png";
        Pattern pattern = Pattern.compile("^data:image/(\\w+);base64,");
        Matcher matcher = pattern.matcher(base64);
        if (matcher.find()) {
            extension = matcher.group(1);
        }
        return extension;
    }

    /**
     * 将图片文件转换为Base64编码的字符串
     *
     * @param imagePath 图片文件路径
     * @return Base64编码的字符串
     */
    public static String encodeImageToBase64(String imagePath) {
        try (FileInputStream imageInFile = new FileInputStream(imagePath);
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = imageInFile.read(buffer)) != -1) {
                byteArrayOutputStream.write(buffer, 0, bytesRead);
            }
            byte[] imageBytes = byteArrayOutputStream.toByteArray();
            return Base64.getEncoder().encodeToString(imageBytes);
        } catch (IOException e) {
            log.error("将图片转换为Base64编码字符串时发生异常", e);
            return null;
        }
    }

    /**
     * 将图片文件转换为Base64编码的字符串（含有扩展名）
     *
     * @param imagePath 图片文件路径
     * @return Base64编码的字符串
     */
    public static String encodeImageToBase64WithExtension(String imagePath) {
        return "data:image/" + getFileExtension(imagePath) + ";base64," + encodeImageToBase64(imagePath);
    }

    /**
     * 获取文件的后缀名
     *
     * @param fileName 文件名
     * @return 文件的后缀名
     */
    public static String getFileExtension(String fileName) {
        if (fileName == null || fileName.isEmpty()) {
            return null;
        }
        int dotIndex = fileName.lastIndexOf('.');
        if (dotIndex == -1 || dotIndex == fileName.length() - 1) {
            return null;
        }
        return fileName.substring(dotIndex + 1);
    }

    public static void main(String[] args) {
        String imagePath = "/Users/mac/Desktop/test.png";
        String base64Str = encodeImageToBase64(imagePath);
        if (base64Str != null) {
            System.out.println("Base64编码字符串: " + base64Str);
        } else {
            System.out.println("图片转换失败");
        }
        String fileName = "test.png";
        String fileExtension = getFileExtension(fileName);
        System.out.println("文件后缀名: " + fileExtension);
    }
}
